import { IComponentMeta } from '../shared/types';
import { uid } from '@designable/shared';
import { get, cloneDeep, isEmpty } from 'lodash';

export interface INode {
  id?: string;
  props?: Record<string, any>;
  componentName: string;
  componentMeta: IComponentMeta,
  type?: string;
  w: number;
  h: number;
  x: number;
  y: number;
}

export class Node implements INode {
  id?: string | undefined;
  props?: Record<string, any>;
  componentName: string;
  componentMeta: IComponentMeta;
  type?: string | undefined;
  w: number;
  h: number;
  x: number;
  y: number;

  constructor(node: INode) {
    this.id = node.id || `node_${uid()}`;
    this.props = node.props || this.meta2Props(node.componentMeta);
    this.componentName = node.componentName;
    this.componentMeta = node.componentMeta;
    this.type = node.type;
    this.w = node.w;
    this.h = node.h;
    this.x = node.x;
    this.y = node.y;
  }

  get propsMeta() {
    return get(this.componentMeta, 'props', [])
  }

  meta2Props(componentMeta: IComponentMeta) {
    const result: Record<string, unknown> = {};
    const { props } = componentMeta || [];

    props.forEach((item) => {
      result[item.name] = cloneDeep(item.defaultValue);
    });

    return result;
  }

  validator() {
    for (const item of this.propsMeta) {
      if (get(item, 'rules.type') === 'string' && item.rules.required) {
        if (isEmpty(this.props?.[item.name])) {
          new Error(`${item.desc}不能为空`)
          return;
        }
      }

      if (get(item, 'rules.type') === 'array' && item.rules.required) {
        const value = this.props?.[item.name];
        if (isEmpty(value)) {
          new Error(`${item.desc}不能为空`)
          return;
        }
      }
    }

    return true;
  }

  generateValidateRules() {
    const rules: Record<string, any> = {};
    for (const item of this.propsMeta) {
      if (get(item, 'rules.type') === 'string' && item.rules.required) {
        rules[item.name] = [
          { required: true, message: `${item.desc}不能为空`, trigger: 'blur' }
        ]
      }

      if (get(item, 'rules.type') === 'array' && item.rules.required) {
        const validator = (rule: any, value: any, callback: any) => {
          if (isEmpty(value)) {
            callback(new Error(`${item.desc}不能为空`));
            return;
          }
          callback();
        }
        rules[item.name] = [
          { required: true, validator, message: `${item.desc}不能为空`, trigger: 'blur' }
        ]
      }
    }

    return rules;
  }

  getSchema() {
    return {
      id: this.id,
      type: this.type,
      componentName: this.componentName,
      props: this.props || {},
      w: this.w,
      h: this.h,
      x: this.x,
      y: this.y
    }
  }
}
